<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
use think\Db;
use app\model\Mch;

function actionWithHelloJob($jobQueueName,$jobData){
      
    // 1.当前任务将由哪个类来负责处理。 
    $jobHandlerClassName  = 'app\api\redis\Redis'; 
    // 4.将该任务推送到消息队列，等待对应的消费者去执行
    $isPushed = \think\Queue::push( $jobHandlerClassName , $jobData , 'MQ:'.$jobQueueName );
    // database 驱动时，返回值为 1|false  ;   redis 驱动时，返回值为 随机字符串|false
    if( $isPushed !== false ){  //写入成功
        return true;
    }else{//写入失败
        return false;
    }
}
/**
 * Undocumented 随机数
 *
 * @param string $length 长度
 * @param string $type   类型
 * @return void
 */
function md5key($length = '32',$type=4){
    $rand='';
    switch ($type) {
        case '1':
            $randstr= '0123456789';
            break;
        case '2':
            $randstr= 'abcdefghijklmnopqrstuvwxyz';
            break;
        case '3':
            $randstr= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
        default:
            $randstr= '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
            break;
    }
    $max = strlen($randstr)-1;
    mt_srand((double)microtime()*1000000);
    for($i=0;$i<$length;$i++) {
       $rand.=$randstr[mt_rand(0,$max)];
    }
    return $rand;
}
/**
 * Undocumented redis限制并发
 *
 * @return void
 */
function redis_concurrent($key,$limit,$time='60'){
    $redis = new \Predis\Client();
    $check = $redis->ttl($key); 

    if($check > 0){
        $count = $redis->incr($key);
        if($count > $limit){
            exit("接口在{$time}秒内已经请求超过最大并发数,请稍后重试");
        }
    }else{
        //过期重新设置该值的过期时间
        $redis->setex($key,$time,1);
    }
   
}
/**
 * 递归菜单
 *
 * @param [type] $arr
 * @param integer $pid
 * @return void
 */
function getTree($data,$pid=0){
    $tree = array();
    foreach($data as $k => $v) {
        //父亲找到儿子
        if($v['pid'] == $pid) { 
            $v['children'] = getTree($data, $v['id']);
            $tree[] = $v;
            unset($data[$k]);
        }
    }
    return $tree;
}
/**
 * Undocumented 商户余额变更记录
 *
 * @param [type] $mch 商户号
 * @param [type] $action 备注
 * @param [type] $balance 变更金额
 * @param [type] $type 类型：1、增加 2、减少 3、冻结 4、解冻 5、支付
 * @return void
 */
function mchRecord($mch,$action,$balance,$type,$order_sn = ''){

    return Db::name("mch_record")->insertGetId(
        [
            "mch_id" =>$mch,
            "balance" =>$balance,
            "type" =>$type,
            "order_sn" =>$order_sn,
            "remark" =>$action,
            "ip" =>get_client_ip(),
            "total_balance" => Mch::mch_balance($mch)
        ]   
    );
}
/**
 * Undocumented 代理商余额变更记录
 *
 * @param [type] $mch 商户号
 * @param [type] $action 备注
 * @param [type] $total_balance 变更后的余额
 * @param [type] $balance 变更金额
 * @param [type] $type 类型：1、手动增加 2、手动减少 3、手动冻结 4、手动解冻 5、商户支付 
 * @return void
 */
function mchAgentRecord($mch,$action,$balance,$type,$order_sn=''){

    return Db::name("agent_record")->insertGetId(
        [
            "agen_id" =>$mch,
            "balance" =>$balance,
            "type" =>$type,
            "order_sn" =>$order_sn,
            "remark" =>$action,
            "ip" =>get_client_ip(),
            "total_balance" =>Mch::mch_balance($mch)
        ]   
    );
}
/**
 * Undocumented 操作记录
 *
 * @return void
 */
function getLog($mid,$type,$action){

    return Db::name("log")->insert(array(
        "mid"    => $mid,
        "ip"     => get_client_ip(),
        "type"   => $type,
        "action" => $action
    ));
}
/**
 * Undocumented 操作记录
 *
 * @return void
 */
function getMchLog($mid,$action,$type = '1'){

    return Db::name("mch_log")->insert(array(
        "mid"    => $mid,
        "ip"     => get_client_ip(),
        "type"   => $type,
        "action" => $action
    ));
}
/**
 * Undocumented 生成随机不重复单号
 *
 * @param string $prefix
 * @return void
 */
function getOrderId($prefix = 'H'){

    return $prefix.date('YmdHis', time()) . substr(microtime(), 2, 4) . sprintf('%03d', rand(1000, 9999));

}
//签名
function get_sign($obj,$KEY){
    $signPars = "";
    ksort($obj);//排序
    foreach($obj as $k => $v){
        if("" != $v && "sign" != $k && 'goods' != $k && 'return_url' != $k){
            $signPars .= $k . "=" .$v . "&";
        }
    }
    $signPars .= "KEY=" . $KEY;
    $my_sign = strtoupper(md5($signPars));
    return $my_sign;
}
/**
 * Undocumented 验证黑名单
 *
 * @return void
 */
function get_is_ip(){
    $white_ip = Db::name("white_ip")->column("white_ip");
    if(in_array(get_client_ip(),$white_ip)){
        
        return false;
    }
    return true;
}
/**
 * Undocumented post请求
 *
 * @param [type] $url
 * @param [type] $param
 * @return void
 */
function curl_post($url,$param){
    $headers = array('Content-Type: application/x-www-form-urlencoded');
    $curl = curl_init(); // 启动一个CURL会话
    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 从证书中检查SSL加密算法是否存在
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
    curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($param)); // Post提交的数据包
    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    $result = curl_exec($curl); // 执行操作
    if (curl_errno($curl)) {
        echo 'Errno'.curl_error($curl);//捕抓异常
    }
    curl_close($curl); // 关闭CURL会话
    return $result;
}
/**
 * Undocumented get请求
 *
 * @param [type] $url
 * @param [type] $param
 * @return void
 */
function curl_get($url,$param){
    $ch = curl_init();
    //设置选项，包括URL
    curl_setopt($ch, CURLOPT_URL, $url.http_build_query($param));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    //执行并获取HTML文档内容
    $output = curl_exec($ch);
    //释放curl句柄
    curl_close($ch);
    return $output;
  }
/**
 * Undocumented json请求
 *
 * @param [type] $url
 * @param [type] $param
 * @return void
 */
function curl_json($url, $param){
    if(is_array($param)){
        $param = json_encode($param);
    }
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL,$url );
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($curl,CURLOPT_POST,1);
    curl_setopt($curl,CURLOPT_POSTFIELDS,$param);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($param)
        )
    );
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $res = curl_exec($curl);
   
    if(curl_errno($curl))
    {
        echo 'Curl error: ' . curl_error($curl);
    }
    curl_close($curl);
    return $res;
}
/**
 * Undocumented 获取一条数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @return void
 */
function get_one($KEY,$id){
    $client = new \Predis\Client();

    $info = $client->zrangebyscore($KEY,$id,$id);
   
    if(!empty($info)){
        return json_decode($info[0],true);
    }
    return false;
}
/**
 * Undocumented 根据id获取数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @return void
 */
function get_list($KEY,$id){

    $client = new \Predis\Client();
    
    $list = $client->zrangebyscore($KEY,$id,$id);
    if(!empty($list)){
        foreach ($list as $key => $value) {
            $list[$key] = json_decode($value,true);
        }
        return $list;
    }
    return false;
}
/**
 * Undocumented 删除一条数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @return void
 */
function get_one_del($KEY,$id){

    $client = new \Predis\Client();
    
    return $client->zremrangebyscore($KEY,$id,$id);
}
/**
 * Undocumented 删除所有数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @return void
 */
function get_all_del($KEY){

    $client = new \Predis\Client();
    
    return $client->del($KEY);
}

/**
 * Undocumented 插入一条数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @param [type] $data
 * @return void
 */
function get_one_insert($KEY,$id,$data){
    get_one_del($KEY,$id);
    $redis = new \Predis\Client();
    
    if(!is_array($data)){
        $data = json_decode($data,true);
    }
    $redis->ZADD($KEY,$id,json_encode($data));
}
/**
 * Undocumented 批量插入数据
 *
 * @param [type] $KEY
 * @param [type] $id
 * @param [type] $data
 * @return void
 */
function get_list_insert($KEY,$list,$pid = 'id'){
    get_all_del($KEY);
    //不是数组
    if(!is_array($list)){
        $list = json_decode($list,true);
    }
    $redis = new \Predis\Client();
    foreach ($list as $value) {
        
        $redis->ZADD($KEY,$value[$pid],json_encode($value)); 
    }
}
/**
 * Undocumented 获取有序集合的所有数据
 *
 * @param [type] $key 
 * @return void
 */
function get_list_k($key){

    $redis = new \Predis\Client();
    $list = $redis->ZRANGE($key,0,-1);
    if($list){
        foreach ($list as $key => $value) {
            $list[$key] = json_decode($value,true);
        }
        return $list;
    }
    return false;
}
/**
 * Undocumented 递归
 *
 * @param [type] $arr
 * @return void
 */
function make_tree($arr){
    if(!function_exists('make_tree1')){
        function make_tree1($arr, $parent_id=0){
            $new_arr = array();
            foreach($arr as $k=>$v){
                if($v['pid'] == $parent_id){
                    $new_arr[] = $v;
                    unset($arr[$k]);
                }
            }
            foreach($new_arr as &$a){
                $a['children'] = make_tree1($arr, $a['id']);
            }
            return $new_arr;
        }
    }
    return make_tree1($arr);
}
/**
 * Undocumented 菜单添加样式
 *
 * @param [type] $arr
 * @return void
 */
function make_tree_with_namepre($arr)
{
    $arr = make_tree($arr);
    if (!function_exists('add_namepre1')) {
        function add_namepre1($arr, $prestr='') {
            $new_arr = array();
            foreach ($arr as $v) {
                if ($prestr) {
                    if ($v == end($arr)) {
                        $v['title'] = $prestr.'└─ '.$v['title'];
                    } else {
                        $v['title'] = $prestr.'├─ '.$v['title'];
                    }
                }
                if ($prestr == '') {
                    $prestr_for_children = '　 ';
                } else {
                    if ($v == end($arr)) {
                        $prestr_for_children = $prestr.'　　 ';
                    } else {
                        $prestr_for_children = $prestr.'│　 ';
                    }
                }
                $v['children'] = add_namepre1($v['children'], $prestr_for_children);

                $new_arr[] = $v;
            }
            return $new_arr;
        }
    }
    return add_namepre1($arr);
}
/**
 * @param $arr
 * @param int $depth，当$depth为0的时候表示不限制深度
 * @return string
 */
function make_option_tree_for_select($arr, $depth=0,$id='')
{
    
    $arr = make_tree_with_namepre($arr);
    if (!function_exists('make_options1')) {
        function make_options1($arr, $depth, $recursion_count=0, $id='') {
            $recursion_count++;
            $str = '';
            foreach ($arr as $v) {
                $selected = '';
                if($v['id'] == $id){
                    $selected = 'selected';
                }
                $str .= "<option value=".$v['id']." {$selected} data-depth=".$v['pid'].">".$v['title']."</option>";
                if ($v['pid'] == 0) {
                    $recursion_count = 1;
                }
                if ($depth==0 || $recursion_count<$depth) {
                    $str .= make_options1($v['children'], $depth, $recursion_count,$id);
                }
            }
            return $str;
        }
    }
    return make_options1($arr, $depth,$recursion_count=0, $id);
}
/**
 * Undocumented 菜单
 *
 * @param string $status 1、后台 2、商户
 * @param string $type 隐藏 2、显示
 * @return void
 */
function __menu($where='',$status='1',$type=''){
    
    $client = new \Predis\Client();
    $list = $client->get('menu');//读取
    if(!$list){
        $client->set('menu',json_encode(Db::name("menu")->select()));
        $list = $client->get('menu');//读取
    }
    $list = json_decode($list,true);
    
    $data = array_filter($list,function($item)use ($status,$type){ return $item['status']==$status && (!empty($type) ? $item['type']==$type : '1=1');});
   
    //排序
    $cmf_arr = array_column($data, 'sort');
    array_multisort($cmf_arr, SORT_DESC, $data);
    if(empty($where)){
        return $data;
    }
    
    return node($where,$data);
} 
/**
 * Undocumented 节点
 *
 * @param [type] $where
 * @param [type] $data
 * @return void
 */
function node($where,$data){
    
    if(is_array($where)){//根据当前落雨，获取节点id
        $where = $where[0];
        $list = array_filter($data, function($item) use ($where) { return $item['action'] == $where; });
        $info = array_pop($list);
        return $info['id'];
    }else{//根据节点id，获取菜单
        $result = [];
        $attr = explode(",",$where);
        foreach ($data as  $value) {
            foreach ($attr as $v) {
                if($v == $value['id']){
                    $result[] = $value;
                }
            }
        }
        return $result;
    }
    
}

